/*
 * interfacetests.c
 * Collection of tests to test
 * the interface.c file
 *  Created on: Mar 2, 2014
 *      Author: Charles_OSU
 */



#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "rngs.h"
#include <math.h>
#include "interface.h"
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include<ctype.h>
#include "helper.h"




#define DEBUG 0
#define NOISY_TEST 1

// prototypes
void printKingdomSupplyCount(int *k, struct gameState *state, FILE *out);
int testInterfacePrint(int pp, struct gameState *state);
int testprintHand(int pp, struct gameState *state);
int testprintDeck(int pp, struct gameState *state);
int testprintPlayed(int pp, struct gameState *state);
int testprintDiscard(int pp, struct gameState *state);
int testprintSupply(struct gameState *state);
int testprintState(struct gameState *state);



int testprintHand(int pp, struct gameState *state){

	int err = 0;
	if((int)state->handCount < 1 ) { err = err + 1; }
	else {	printHand(pp, state); }

	return err;
}


int testprintDeck(int pp, struct gameState *state){

	int err = 0;
	if((int)state->deckCount < 1 ) { err = err + 1; }
		else { printDeck(pp, state); }

	return err;
}


int testprintPlayed(int pp, struct gameState *state){

	 int err = 0;

	 if((int)state->playedCardCount < 1 ) { err = err + 1; }
	 	else { printPlayed(pp, state); }

	 return err;
}


int testprintDiscard(int pp, struct gameState *state){

	int err = 0;

	if((int)state->discardCount < 1 ) { err = err + 1; }
		else {printDiscard(pp, state); }

	return err;

}


int testprintSupply(struct gameState *state){

	 int err = 0;

	 if((int)state->supplyCount < 1 ) { err = err + 1; }
	 	else {printSupply(state); }

	 return err;

}


int testprintState(struct gameState *state){

	int err = 0;

	if((int)state->phase < 0 ) { err = err + 1; }
		else {printState(state); }

	return err;

}



int testInterfacePrint(int pp, struct gameState *state){
    // Print interface fucntions to screen after each turn for
	// manual inspection and comparison against stats in interfacetests.out file

	int numErrors = 0;


	printf("The players hand :\n");
	numErrors += testprintHand(pp, state);

	printf("The players deck :\n");
	numErrors +=  testprintDeck(pp, state);

	printf("The player played: \n");
	numErrors +=  testprintPlayed(pp, state);

	printf("The discard was :\n");
	numErrors +=  testprintDiscard(pp, state);

	printf("Our supply is: \n");
	numErrors +=  testprintSupply(state);

	printf("The current state is: \n");
	numErrors +=  testprintState(state);

	 return numErrors;

}


/*
Function prints the name action cards and supply count
*/

void printKingdomSupplyCount(int *k, struct gameState *state, FILE *out){

    int i, n;
    char* card = (char*) malloc(sizeof(char)*MAX_STRING_LENGTH);


    printf("Kingdom Card Supply counts: \n");
    fprintf (out, "Kingdom Card Supply counts are: \n");
    for (i=0; i<10; i++){
        cardNumToName(k[i], card);
        printf("\t%s = %i\n", card, state->supplyCount[k[i]]);
        fprintf (out, "\t%s = %i\n", card, state->supplyCount[k[i]]);
        n = 0;
        while(card[n] != '\0' && n != 255){
            card[n] = '\0';
            n++;
        }
    }

}



int main (int argc, char** argv) {


	int x;
	int testNums = 10; // number of tests to run
	int numErrors = 0; // counter for number of errors found
	struct gameState *gsPre = newGame();
	int pp;

	// now seed the game
	  SelectStream(3);
	  /* ---------------------------------------------------------------
	   * Use this function to set the state of the current random number
	   * generator stream according to the following conventions:
	   *    if x > 0 then x is the state (unless too large)
	   *    if x < 0 then the state is obtained from the system clock
	   *    if x = 0 then the state is to be supplied interactively
	   *    So I will set set to -1 to let clock generate seed
	   * ---------------------------------------------------------------
	   */
	  PutSeed(-1);

	  // Sets clean state each time
	  setState(gsPre);

	  // Setup my file constructor
	    char filename[] = "interfacetests.out";
	    FILE *fp;
	  	fp = fopen(filename, "w");



	  	 fprintf(fp, "Testing Interface Start\n");

	  printf("Testing Interface Start\n");
	  // See if help will print. Send output to file and screen


	  // manual test to check printHelp
	  printHelp();


	  for (x = 0; x < testNums; x++) {

    // Set the kingdom cards to nothing at first.
		int k[10] = {};

		  SelectStream(3);
		  PutSeed(-1);

	  fprintf(fp, "Starting game %d.\n\n", x);
	  printf ("Starting game %d.\n\n", x);

	  // Call from interface selectKingdomCards to get cards
	  selectKingdomCards(-1, k);
	  printKingdomSupplyCount(k, gsPre, fp);

	  // Call to initialize game
	  initializeGame(gsPre->numPlayers, k, -1, gsPre);



	  // Call to print my supply
	//  printSupply(gsPre);


	  int money = 0;
	  int smithyPos = -1;
	  int adventurerPos = -1;
	  int salvagerPos = -1;
	  int great_hallPos = -1;
	  int i=0;
	  int numSmithies = 0;
	  int numAdventurers = 0;
	  int numSalvager = 0;
	  int numGreat_Hall = 0;
	  int smithywasplayed = 0;
	  int adventurewasplayed = 0;
	  int salvagerplayed = 0;
	  int great_hallplayed = 0;

	  while (!isGameOver(gsPre)) {
	    money = 0;
	    smithyPos = -1;
	    adventurerPos = -1;
	    salvagerPos = -1;
	    great_hallPos = -1;




	    for (i = 0; i < numHandCards(gsPre); i++) {
	      if (handCard(i, gsPre) == copper)
	    money++;
	      else if (handCard(i, gsPre) == silver)
	    money += 2;
	      else if (handCard(i, gsPre) == gold)
	    money += 3;
	      else if (handCard(i, gsPre) == smithy)
	    smithyPos = i;
	      else if (handCard(i, gsPre) == adventurer)
	    adventurerPos = i;
	      else if (handCard(i, gsPre) == salvager)
	    	 salvagerPos = i;
	      else if (handCard(i, gsPre) == great_hall)
	    	  great_hallPos = i;
	    }

	    fprintf(fp, "Player %d's turn\n", gsPre->whoseTurn);
	    printf("Player %d's turn\n", gsPre->whoseTurn);

	      if (smithyPos != -1 && smithywasplayed < 2) {
	    	  fprintf(fp, "smithy played from position %d\n", smithyPos);
	        printf("smithy played from position %d\n", smithyPos);
		        smithywasplayed += 1;

		// Get the current players turn and send in the adventurer card and test it.
			pp = whoseTurn(gsPre);
			// Test Smithy card
			if (playCard(smithyPos, -1, -1, -1, gsPre) < 0){
				numErrors = numErrors + 1;
			}


			 fprintf(fp, "smithy played.\n");
			printf("smithy played.\n");


	      } // end if (smithyPos != -1)



	    else  if (adventurerPos != -1 && adventurewasplayed < 2) {
	    	 fprintf(fp, "adventurer played from hand position %d\n", adventurerPos);
	        printf("adventurer played from hand position %d\n", adventurerPos);
		    adventurewasplayed = adventurewasplayed + 1;

		// Get the current players turn and send in the adventurer card and test it.
		pp = whoseTurn(gsPre);
		if (playCard(adventurerPos, -1, -1, -1, gsPre) < 0){
						numErrors = numErrors + 1;
					}

		    } // end if


	    else if (salvagerPos != -1 && salvagerplayed < 2) {
	    	fprintf(fp, "Salvager played from hand position %d\n", salvagerPos);
	   	   	 	  printf("Salvager played from hand position %d\n", salvagerPos);

	   	   	 	// Get the current players turn and send in the salvager card and test it.
	   	   	 	  pp = whoseTurn(gsPre);
	   	   	 	// Test salvager card
	   	   	if (playCard(salvagerPos, -1, -1, -1, gsPre) < 0)
	   	   	{
	   	   		numErrors = numErrors + 1;
	   	   	}

	   	   	       salvagerplayed = salvagerplayed + 1;

	   	   	  }

	    else if (great_hallPos != -1 && great_hallplayed < 2) {
	    	fprintf(fp, "great_hall played from hand position %d\n", great_hallPos);
	   	   	 	  printf("great_hall played from hand position %d\n", great_hallPos);

	   	   	 	// Get the current players turn and send in the great_hall card and test it.
	   	   	 	  pp = whoseTurn(gsPre);
	   	   	 	// Test great_hall card
	   	    	if (playCard(great_hallPos, -1, -1, -1, gsPre) < 0)
	   	   	   	   	{
	   	   	   	   		numErrors = numErrors + 1;
	   	   	   	   	}

	   	   	  great_hallplayed = great_hallplayed + 1;

	   	   	  }
	    else 	{
	    	// If we do not have any of these cards in hand but we want to play others then
	    	// we will loop through the hand and play what we have.

	    	int rancarddpos = -1;
	    	int i =0;
	    	 for (i = 0; i < numHandCards(gsPre); i++) {
	    		      if (handCard(i, gsPre) == curse)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == council_room)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == feast)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == gardens)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == mine)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == remodel)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == village)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == baron)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == minion)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == tribute)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == ambassador)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == cutpurse)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == embargo)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == outpost)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == sea_hag)
	    		    	  rancarddpos = i;
	    		      else if (handCard(i, gsPre) == treasure_map)
	    		       	 rancarddpos = i;
	    		    }
	    	 pp = whoseTurn(gsPre);
	    	 //printHand(pp, gsPre);
	    	 int cardinmyhand = -1;
	    	 int random[11] = { council_room, feast, gardens, mine, village, baron, minion, tribute, ambassador, outpost, sea_hag};
	    	 int bool = 0;
	    	 if(rancarddpos >= -1){


	    	 int number = floor(Random() * ((11-0)+1));
	    	 rancarddpos = 1;
	    	 cardinmyhand = random[number];
	    	 bool = 1;
	    	  }


	    	 if(rancarddpos >= -1)
	    	 {

	    		 if (bool != 1){
	    			 cardinmyhand = handCard(rancarddpos,gsPre);
	    		 }

	    		 fprintf(fp, "Played a Randomly selected card to exercise the program further from position %d\n", rancarddpos);
	    	  printf("Played a Randomly selected card in hand from position %d\n", rancarddpos);




	    	  // Get the current players turn and send in Randomly selected card in hand and test it.
	    		  pp = whoseTurn(gsPre);

	    		  // Play Randomly selected card in hand check for errors
	    		  if (playCard(rancarddpos, -1, -1, -1, gsPre) < 0)
	    		 	{
	    		  	   numErrors = numErrors + 1;
	    		   	}
	    		 }

	    		}
	      // test print fucntions and send some values to screen for
	    	  // manual inspection
	    	   			   pp = whoseTurn(gsPre);
	    	   			   // Calls a suite that will test all print funcitons
	    	   			   testInterfacePrint( pp, gsPre);


	            money = 0;
	      		i=0;
	      		while(i<numHandCards(gsPre)){
	      		  if (handCard(i, gsPre) == copper){
	      		    playCard(i, -1, -1, -1, gsPre);
	      		    money++;
	      		  }
	      		  else if (handCard(i, gsPre) == silver){
	      		    playCard(i, -1, -1, -1, gsPre);
	      		    money += 2;
	      		  }
	      		  else if (handCard(i, gsPre) == gold){
	      		    playCard(i, -1, -1, -1, gsPre);
	      		    money += 3;
	      		  }
	      		  i++;
	      		} // end while
	      		 if (money >= 8) {
	      			 	 	fprintf(fp, "%d bought province\n", gsPre->whoseTurn);
	      			        printf("%d bought province\n", gsPre->whoseTurn);
	      			        buyCard(province, gsPre);
	      			      }
	      			      else if ((money >= 6) && (numAdventurers < 4)) {
	      			    	fprintf(fp,"%d bought adventurer\n" , gsPre->whoseTurn);
	      			        printf("%d bought adventurer\n" , gsPre->whoseTurn);
	      			        buyCard(adventurer, gsPre);
	      			        numAdventurers++;
	      			      }

	      			      else if ((money >= 4) && (money < 5) && (numSmithies < 3)) {
	      			    	fprintf(fp,"%d bought smithy\n", gsPre->whoseTurn);
	      			  	    printf("%d bought smithy\n", gsPre->whoseTurn);
	      			  	    buyCard(smithy, gsPre);
	      			  	    numSmithies++;
	      			  	      }

	      			      else if ((money >= 4) && (numSalvager < 4)) {
	      			    	fprintf(fp,"%d bought salvager\n", gsPre->whoseTurn);
	      			     	printf("%d bought salvager\n", gsPre->whoseTurn);
	      			     	buyCard(salvager, gsPre);
	      			     	numSalvager++;
	      			      }
	      			      else if ((money >= 3) && (numGreat_Hall < 4)) {
	      			    	fprintf(fp,"%d bought great_hall\n", gsPre->whoseTurn);
	      			    	printf("%d bought great_hall\n", gsPre->whoseTurn);
	      			    	buyCard(great_hall, gsPre);
	      			    	numGreat_Hall++;
	      			    	 }
	      			      else if (money >= 6){
	      			       fprintf(fp,"%d bought gold\n", gsPre->whoseTurn);
	      			       printf("%d bought gold\n", gsPre->whoseTurn);
	      			       buyCard(gold, gsPre);
	      			          }
	      			      else if (money >= 3){
	      			    	fprintf(fp,"%d bought silver\n", gsPre->whoseTurn);
	      			        printf("%d bought silver\n", gsPre->whoseTurn);
	      				    buyCard(silver, gsPre);

	      			      }
	      		 	 	 fprintf(fp,"endTurn\n");
	      		 	 	 printf("endTurn\n");
	      			     endTurn(gsPre);
	      			     // Print the gamestate to file
	      			   printGameSummary(*gsPre, fp, x, gsPre->numPlayers);



	  } // end of While

	  fprintf(fp, "Finished game.\n\n");
	  printf ("Finished game.\n\n");




	  fprintf(fp,"Number of players were: %d\n", gsPre->numPlayers);
	  printf("Number of players were: %d\n", gsPre->numPlayers);
	  // After each run we need to reset everything otherwise the
	    // whole thing crashes after a few hundred or so tests.

	  int winners[MAX_PLAYERS];
	  getWinners(winners, gsPre);
	  printScores(gsPre);


	  free(gsPre);
	  struct gameState *gsPre = malloc(sizeof(struct gameState));
	    setState(gsPre);
	    gsPre->hand[0][gsPre->handCount[0]] = -1;
	   	gsPre->hand[0][gsPre->handCount[0] + 1] = -1;

	  }




	  printf ("Testing Interface End \nALL TESTS RUN!\n");

	  free(gsPre);

	  if (numErrors == 0){
		  fprintf(fp,"There were no errors found in this tests!\n");
		  printf("There were no errors found in this tests!\n");
	  }
	  else if(numErrors > 0){
		  fprintf(fp,"There were %d errors in the tests run!\n",numErrors);
		  printf("There were %d errors in the tests run!\n",numErrors);
	  }
	  else{
		  fprintf(fp,"The error count was not 0 or more so the tests puked! \n");
		  printf("The error count was not 0 or more so the tests puked! \n");
	  }

	return 0;
}




